#pragma once

#include <string>
#include <mutex>

using namespace std;

#ifndef WIN32
#   include <sys/stat.h>
#   include <sys/file.h>
#   include <sys/time.h>
#   include <unistd.h>
#endif

#ifdef ENABLE_USE_LOGCPLUS 
#include "logcplus/logcplus.h"
using namespace logcplus;
#endif 

#include "topconn_cross_platform.hpp"

#define TOPCONN_DEBUG_LOG         "topconn.log"
#define TOPCONN_DEUBG_ENV_TAG     "TOPCONN_LOGLEVEL"

namespace topconn
{
    typedef enum
    {
        L_TRACE = 0,
        L_DEBUG,
        L_INFO,
        L_WARN,
        L_ERROR
    }eLogLevel_t;

    char* topconn_gettime(char* datetime);
    long  topconn_getfilesize(const char* psFileName);
    long  topconn_getfilesize(FILE* hFile);
    bool  topconn_exists_file(const char* psFileName);

    class topconn_log
    {
    private:
        FILE* m_fpDebug;
        
        topconn_log() = default;
        topconn_log(const topconn_log& ) = default;

        void rotate();

        static topconn_log* m_instance;
        static std::mutex m_lock;
        static bool m_status;

        class AutoRelease
        {
            public:
            ~AutoRelease()
            {
                if (topconn_log::m_instance)
                {
                    std::lock_guard<std::mutex> _lock(topconn_log::m_lock);
                    if (topconn_log::m_instance)
                    {
	                    topconn_log::m_instance->close();
	                    delete topconn_log::m_instance;
	                    topconn_log::m_instance = nullptr;
                    }
                }
            };
        };	    
        static AutoRelease m_release;
    public:
        int openlog();
        void close();
        void writelog(const char* file,const char* function,int line,int level,const char* fmt,...);
        void writelog(int dbsLevel,int level,const char* data);	
        static topconn_log* rootLog();			
    };

#ifndef ENABLE_USE_LOGCPLUS  
    #define TLOG_TRACE(fmt, ...) topconn_log::rootLog()->writelog(__FILE__, __FUNCTION__ , __LINE__,topconn::L_TRACE,fmt,##__VA_ARGS__);
    #define TLOG_DEBUG(fmt, ...) topconn_log::rootLog()->writelog(__FILE__, __FUNCTION__ , __LINE__,topconn::L_DEBUG,fmt,##__VA_ARGS__);
    #define TLOG_INFO( fmt, ...) topconn_log::rootLog()->writelog(__FILE__, __FUNCTION__ , __LINE__,topconn::L_INFO ,fmt,##__VA_ARGS__);
    #define TLOG_WARN( fmt, ...) topconn_log::rootLog()->writelog(__FILE__, __FUNCTION__ , __LINE__,topconn::L_WARN ,fmt,##__VA_ARGS__);
    #define TLOG_ERROR(fmt, ...) topconn_log::rootLog()->writelog(__FILE__, __FUNCTION__ , __LINE__,topconn::L_ERROR,fmt,##__VA_ARGS__);
#endif

}
